// FindEye.h: interface for the CFindEye class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(FIND_EYE_ML_H)
#define FIND_EYE_ML_H

#if _MSC_VER > 1000
#pragma once
#endif 

#define NULL_POINTER(x) x = NULL
#define SAFE_RELEASE(x) if(x) {delete x; x = NULL;}

#define STDEYEIMAGESIZE      12
#define EYESTARTSTEP         1.0
#define EYEWIDTH			 24
#define EYEHEIGHT			 12

#define MAX_EYE_SCALE         20 //50
#define MIN_EYE_STD_VARIANCE  80
#define MAX_EYE_STD_VARIANCE  5000
#define NUM_EYE_SMODEL        10
#define  RESTRICT_NUM_Ratio   0.5

#include <vector>
#include <algorithm>
using namespace std;
#pragma warning(disable:4786)
#include <map>
typedef multimap<double,POINT,greater<double> > doubleMap;


struct EyeModel_ML
{
	int m_nMaxLayNum;	
	int maxT;		   

	int *cascade;
	double *finalthreshold;
    int (*finaltype)[6];
	double *finalh;
	int *finalsign;
	double *errorset;
	int *featureset;	
	int (*featurescale)[MAX_EYE_SCALE][4];
	double *apha;
};

class CFindEye_ML  
{
public:
	bool LoadOneModelFromFile(EyeModel_ML* *m_ppModel, CString szModelFileName);
	BOOL LoadOneModelFromResource(EyeModel_ML **m_ppModel,int nIndex,int nLayerUsed);
	bool LoadModelFromFile();
	bool MLFindEye(int PosX,int PosY,double* mScore,int ScaleNo, int iModelIndex, int MaxLayer = 5);
	CFindEye_ML();
	virtual ~CFindEye_ML();
public:
	bool GetEyePix(BYTE** ppSrcImage, int iWidth, int iHeight, RECT rcFaceRegion,  POINT* ptLeftEye, POINT* ptRightEye);
	bool m_fFindImageInList;
	int iImgIndex;
	CString strCurDocFilename;
	BOOL merge(int type=0);
	void GetGrayImg(BYTE **ppImg, int nWidth, int nHeight);
	double GetVariance(int scalenum, int x, int y, int winm, int winn);

	double PrepareModel(const int StdImageSize);
	void GetItgImage(int **pItgImage,BYTE **pImage, int ImageWidth, int ImageHeight);
	int GetFeatureValue(int **itgimage,int type,int mm,int nn, int x, int y,int x_start, int y_start,double Ratio);
	double GetFilterValueWithImage(int **ppzlImageData, int FeaType, int RECTWidth,int RECTHeight,int Posx,int Posy,int StartX, int StartY,double Ratio);
	
    int m_nMaxFilterNum;
    int m_nMaxLayerNum;
	int m_nMaxScaleNum;
	BYTE** m_ppGrayImg;
	int **m_ppItgImg;
	int **m_ppItgImageXX;
	float  m_fConfThr[30000];
	EyeModel_ML* m_pModel;
	EyeModel_ML* m_pArrModel[10];
	int m_nModel;
	int m_nWidth;
	int m_nHeight;
	unsigned long m_nWindowSize[MAX_EYE_SCALE];
	unsigned long m_nWindowArea[MAX_EYE_SCALE];
	unsigned long SubWindowWidth[MAX_EYE_SCALE];
	unsigned long SubWindowHeight[MAX_EYE_SCALE];
	double m_dbScaleArea[MAX_EYE_SCALE];

    class CEyePosition_ML
	{
	public:
		CEyePosition_ML(int xx, int yy, int num, double dbConf): 
		  x(xx), y(yy), DetectionSum(num), Confidence(dbConf) {};
		~CEyePosition_ML() {};

		int x;
		int y;
		int DetectionSum;
		float Confidence;
		float sumConfidence;
		float MultiConf[20];
		float ratio;
		float avrConf;
		int width;
		int height;
	};
	
	class CCoarseEyePosInfo
	{
	public:
		CCoarseEyePosInfo(int xx, int yy, int scalenum, int w_center, int h_center): 
		  iPtX(xx), iPtY(yy), iScaleNum(scalenum), 
		  iDistPtXToCenterX(w_center), iDistPtYToCenterY(h_center) {};
		
		~CCoarseEyePosInfo() {};

		int iPtX;
		int iPtY;
		int iScaleNum;
		int iDistPtXToCenterX;
		int iDistPtYToCenterY;
	};

	std::vector<CCoarseEyePosInfo> m_CoareseLeftEyesInfo;
	std::vector<CCoarseEyePosInfo> m_CoareseRightEyesInfo;

	std::vector<CEyePosition_ML> m_Left_DetectionPoint;
	std::vector<CEyePosition_ML> m_Right_DetectionPoint;
	std::vector<CEyePosition_ML> m_Left_MergePoint;
	std::vector<CEyePosition_ML> m_Right_MergePoint;

private:
	int m_nFeatureNum;
	int m_nMaxFeatureNum;
	double m_fRatio;
	int m_nFilterNum;
	int m_nLayer;
	int m_nStep;
	double m_ScaleSize;
	double m_dbStartscale;
	int m_nStdImageSize;
	BOOL m_nMerge;
	int m_XXTable[256]; 
	float m_rgbRToY[256];   
    float m_rgbGToY[256];    
    float m_rgbBToY[256];  

	RECT m_rcFaceRect;	
	void SAFE_RELEASE300(unsigned char** ppImg, int nDim );
    void SAFE_RELEASE30(int** ppImg, int nDim );
	void SAFE_RELEASE_EYE_MODEL(EyeModel_ML* pModel);
};

#endif 
